/*
 * Copyright (c) 2017. 杭州端点网络科技有限公司.  All rights reserved.
 */

package com.jiantong.user.impl.service;

import com.google.common.base.Throwables;
import com.jiantong.common.enums.UserRole;
import com.jiantong.common.enums.UserStatus;
import com.jiantong.common.enums.UserType;
import com.jiantong.common.util.MD5Util;
import com.jiantong.user.enums.OrganizationStatus;
import com.jiantong.user.enums.OrganizationType;
import com.jiantong.user.impl.dao.*;
import com.jiantong.user.impl.manager.OrganizationManager;
import com.jiantong.user.model.*;
import com.jiantong.user.service.OrganizationWriteService;
import io.terminus.boot.rpc.common.annotation.RpcProvider;
import io.terminus.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author : panxin
 */
@Slf4j
@Service
@RpcProvider
public class OrganizationWriteServiceImpl implements OrganizationWriteService {

    private final OrganizationDao organizationDao;
    private final ButcherFactoryDao butcherFactoryDao;
    private final BreedFactoryDao breedFactoryDao;
    private final GovernmentDao governmentDao;
    private final DepartmentDao departmentDao;
    private final OrganizationManager organizationManager;

    @Autowired
    public OrganizationWriteServiceImpl(OrganizationDao organizationDao, ButcherFactoryDao butcherFactoryDao, BreedFactoryDao breedFactoryDao, GovernmentDao governmentDao, DepartmentDao departmentDao, OrganizationManager organizationManager) {
        this.organizationDao = organizationDao;
        this.butcherFactoryDao = butcherFactoryDao;
        this.breedFactoryDao = breedFactoryDao;
        this.governmentDao = governmentDao;
        this.departmentDao = departmentDao;
        this.organizationManager = organizationManager;
    }

    @Override
    public Response<Long> createGovernment(Government government) {
        try {
            if (government == null) {
                return Response.fail("government.is.null");
            }

            String name = government.getName();
            Integer status = OrganizationStatus.NORMAL.value();
            Integer type = OrganizationType.GOVERNMENT.value();

            Organization organization = new Organization();
            organization.setName(name);
            organization.setType(type);
            organization.setStatus(status);

            government.setLevel(1);
            government.setHasChildren(false);

            User user = generateUser();
//            user.setRoles(Collections.singletonList(UserRole.GOVERNMENT.name()));

            OrganizationUser organizationUser = generateOrganizationUser(organization);
            organizationUser.setRoleName(UserRole.GOVERNMENT.name());
            organizationUser.setRoleType(1);

            return Response.ok(organizationManager.createGovernment(organization, government, user, organizationUser));
        } catch (Exception e) {
            log.error("failed to create government = {}, cause : {}", government, Throwables.getStackTraceAsString(e));
            return Response.fail("create.government.failed");
        }
    }

    @Override
    public Response<Long> createButcher(ButcherFactory factory) {
        try {
            if (factory == null) {
                return Response.fail("butcher.factory.is.null");
            }

            String name = factory.getName();
            Integer status = OrganizationStatus.NORMAL.value();
            Integer type = OrganizationType.BUTCHER.value();

            Organization organization = new Organization();
            organization.setName(name);
            organization.setType(type);
            organization.setStatus(status);

            User user = generateUser();
//            user.setRoles(Collections.singletonList(UserRole.BUTCHER.name()));

            OrganizationUser organizationUser = generateOrganizationUser(organization);
            organizationUser.setRoleName(UserRole.BUTCHER.name());
            organizationUser.setRoleType(1);

            return Response.ok(organizationManager.createGovernment(organization, factory, user, organizationUser));
        } catch (Exception e) {
            log.error("failed to create butcher factory = {}, cause : {}", factory, Throwables.getStackTraceAsString(e));
            return Response.fail("create.butcher.factory.failed");
        }
    }

    @Override
    public Response<Long> createBreeder(BreedFactory factory) {
        try {
            if (factory == null) {
                return Response.fail("breed.factory.is.null");
            }

            String name = factory.getName();
            Integer status = OrganizationStatus.NORMAL.value();
            Integer type = OrganizationType.BREEDER.value();

            Organization organization = new Organization();
            organization.setName(name);
            organization.setType(type);
            organization.setStatus(status);

            User user = generateUser();
//            user.setRoles(Collections.singletonList(UserRole.BREEDER.name()));

            OrganizationUser organizationUser = generateOrganizationUser(organization);
            organizationUser.setRoleName(UserRole.BREEDER.name());
            organizationUser.setRoleType(1);

            return Response.ok(organizationManager.createGovernment(organization, factory, user, organizationUser));
        } catch (Exception e) {
            log.error("failed to create breed factory = {}, cause : {}", factory, Throwables.getStackTraceAsString(e));
            return Response.fail("create.breed.factory.failed");
        }
    }

    @Override
    public Response<Long> create(Organization organization) {
        try {
            organizationDao.create(organization);
            return Response.ok(organization.getId());
        }catch (Exception e){
            log.error("failed to create breed factory = {}, cause : {}", organization, Throwables.getStackTraceAsString(e));
            return Response.fail("create.breed.factory.failed");
        }
    }

    @Override
    public Response<Boolean> update(Organization organization) {
        try {
            return Response.ok(organizationDao.update(organization));
        }catch (Exception e){
            log.error("failed to update ", organization, Throwables.getStackTraceAsString(e));
            return Response.fail("update.failed");
        }
    }

    private OrganizationUser generateOrganizationUser(Organization organization) {
        OrganizationUser user = new OrganizationUser();
        user.setOrganizationType(organization.getType());
        user.setOrganizationName(organization.getName());
        return user;
    }

    private User generateUser() {
        User user = new User();
        user.setName("djt_user_");
        user.setStatus(UserStatus.NORMAL.value());
        user.setType(UserType.NORMAL.value());
        user.setPassword(MD5Util.encrypt("123456")); // todo
        return user;
    }

}
